package ch.fusun.baron.player.api;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import ch.fusun.baron.core.datastructures.MirrorMap;
import ch.fusun.baron.data.DataProvider;
import ch.fusun.baron.player.Player;

/**
 * Service for proposing/accepting marriages and reading the married status
 */
public interface MarriageService extends DataProvider {
    /**
     * @param player
     *            The player
     * @return Is the {@link Player} married to someone?
     */
    boolean isMarried(Player player);

    /**
     * @param player
     *            The player
     * @return To whom is the {@link Player} married to (<code>null</code> if
     *         not married)
     */
    Player getSpouse(Player player);

    /**
     * @param proposer
     *            The proposer
     * @param proposedTo
     *            The proposedTo
     * 
     *            Marriages can only be proposed between man and woman and not
     *            in the same family. And not dead.
     */
    void proposeMarriage(Player proposer, Player proposedTo);

    /**
     * @param proposer
     *            The proposer
     * @param proposedTo
     *            The proposedTowhy
     * 
     *            Same prerequisites as in
     *            {@link #proposeMarriage(Player, Player)} plus the marriage
     *            must be proposed
     */
    void acceptMarriage(Player proposer, Player proposedTo);

    /**
     * 
     * @param proposer
     *            The proposer
     * @param proposedTo
     *            The proposedTO
     * 
     *            Declines a marriage proposal
     */
    void declineMarriage(Player proposer, Player proposedTo);

    /**
     * Sets all marriages
     * 
     * @param marriage
     * @param marriageProposals
     * 
     */
    void setMarriageStatus(MirrorMap<Player> marriage,
            Map<Player, Player> marriageProposals);

    /**
     * @param one
     *            The one
     * @param andTheother
     *            The other
     * 
     *            Marries the two
     */
    void marry(Player one, Player andTheother);

    /**
     * @return All married men
     */
    Collection<Player> getAllMarriedMen();

    /**
     * Removes the marriage status for the person
     * 
     * @param person
     *            The person
     */
    void divorce(Player person);

    /**
     * @return All proposals
     */
    List<Entry<Player, Player>> getProposals();
}
